# -*- coding: utf-8 -*-
import os, sys, re, time, subprocess, shutil, hashlib,string,stat,traceback,socket
import xml.dom.minidom 
import platform as plat

toolPath = os.path.split(os.path.realpath(__file__))[0]


versionPath = os.path.realpath(toolPath + '/../../')

tmpUserPassword = ' --username dabaoji --password woowii.0302 --no-auth-cache'

tmpUserPassword1 = ' --username dabaoji --password woowii.0302 --no-auth-cache'

tmpUserPasswordMac = ' --username dabaoji --password woowii.0302 --no-auth-cache'


def GetSvnPath(projectPath):
    global svnPath, tmpUserPassword
    # if svnPath != '' :
        # return svnPath

    # print('[util](GetSvnPath)projectPath:'+projectPath)
    ret, output = call('svn info %s --xml %s' % (projectPath, tmpUserPassword))
    # print('projectPath:' + projectPath)
    if ret != 0:
        print output
        return ''
        
    infoDom = xml.dom.minidom.parseString(output)

    infoElem = infoDom.getElementsByTagName('info')[0]

    commitElem = infoElem.getElementsByTagName('entry')[0].getElementsByTagName('url')[0]

    for textNode in commitElem.childNodes:  
        svnPath = textNode.nodeValue
        return textNode.nodeValue

    return ''

def matchProdcut(name):
    return re.match('^NewPackage-([0-9]+_[0-9]+_[0-9]+_[0-9]+)$', name)

def matchPatch(name):
     return re.match('^([0-9]+_[0-9]+_[0-9]+_[0-9]+)-([0-9]+_[0-9]+_[0-9]+_[0-9]+)-Update$', name)

def doesMatchPatchTgtVersion(name, tgtVersion):
     match = re.match('^([0-9]+_[0-9]+_[0-9]+_[0-9]+)-([0-9]+_[0-9]+_[0-9]+_[0-9]+)-Update$', name)
     if match :
         return match.groups()[1] == encodeVersion(tgtVersion)

     return False

def doesMatchIOSProjectTgtVersion(name, tgtVersion):
     match = re.match('^NewPackage-([0-9]+_[0-9]+_[0-9]+_[0-9]+)-Project$', name)
     if match :
         return match.groups()[0] == encodeVersion(tgtVersion)

     return False

def decodeVersion(version):
    return version.replace('_', '.')

def encodeVersion(version):
    return version.replace('.', '_')

def srcVersion(name):
    match = matchPatch(name)

    if match and len(match.groups()) >= 2:
        groups = match.groups()
        return groups[0]
    else:
        return '0.0.0.0'

def tgtVersion(name):
    match0 = matchProdcut(name)
    match1 = matchPatch(name)

    match = match0 if match0 else match1

    if match:
        groups = match.groups()

        if len(match.groups()) >= 6:
            return groups[1]
        else:
            return groups[0]
    else:
        return '0.0.0.0'

def isVersionValid(version):
    match = re.match('^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', version)

    if match:
        return True

    return False

def decompVersion(version):
    match = re.match('^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)$', version)
    if match and len(match.groups()) == 4:
        groups = match.groups()
        return [int(groups[0]), int(groups[1]), int(groups[2]), int(groups[3])]

    return [0, 0, 0, 0]

def cmpRevision(v0, v1):
    v0 = string.atoi(v0)
    v1 = string.atoi(v1)
    if v0 > v1:
        return 1
    elif v0 < v1:
        return -1
    else:
        return 0

def cmpVersion(v0, v1):
    v0a = decompVersion(v0)
    v1a = decompVersion(v1)
    for (c0, c1) in zip(v0a, v1a):
        if c0 > c1:
            return 1
        elif c0 < c1:
            return -1
    return 0

def localTimeStamp(inTime):
    localTime = time.localtime(inTime)
    return '%s.%02d.%02d-%02d.%02d.%02d' % (localTime[0], localTime[1], localTime[2], localTime[3], localTime[4], localTime[5])

def callRedirect(cmd, redirection):
    returnCode = 0
    try:
        returnCode = subprocess.check_call(cmd + ' > ' + redirection, shell = True)
    except subprocess.CalledProcessError, e:
        returnCode = e.returncode
        traceback.print_exc()
        print("unity run error")
        print(cmd)#.encode('utf-8'))
        print("执行失败，请检查")

    return returnCode

def call(cmd):
    output = ''
    returnCode = 0
    try:
        output = subprocess.check_output(cmd, shell = True)
    except subprocess.CalledProcessError, e:
        output = e.output
        returnCode = e.returncode
        traceback.print_exc()
        print("unity run error")
        print(cmd)#.encode('utf-8'))
        print("执行失败，请检查")

    return returnCode, output

def writeAllText(path, text):
    file = open(path, 'w')
    file.write(text)
    file.close()

def fileMD5(fileName):
    hash_md5 = hashlib.md5()
    with open(fileName, 'rb') as f:
        for chunk in iter(lambda: f.read(4096), b''):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

def PathIsConflict(path):
    isConflict = False
    if os.path.isfile(path) or os.path.isdir(path):
        ret, output = call('svn stat %s' % path)
        if output != '' and output[1] == 'C':
            isConflict = True
            print(path + "is Conflict,pleace resolved first !!!")
    return isConflict

def PathIsLock(path):
    isLock = False
    if os.path.isfile(path) or os.path.isdir(path):
        ret, output = call('svn stat %s' % path)
        if output != '' and output[2] == 'L':
            isLock = True
            print(path + "is lock,pleace cleanup first !!!")
    return isLock

def PathIsLockOrConflict(path):
    IsLockOrConflict = False
    print("开始检查目录" + path)
    if os.path.isfile(path) or os.path.isdir(path):
        ret, output = call('svn stat %s' % path)
        if ret != 0:
            IsLockOrConflict = True
            print(path + " svn出错 返回值不为0")
        if output != '' and (output[1] == 'C' or output[2] == 'L'):
            IsLockOrConflict = True
            if output[1] == 'C':
                print(path + "is Conflict,pleace resolved first !!!")
            else:
                print(path + "is lock,pleace cleanup first !!!")
    else:
        print("找不到路径" + path)
    return IsLockOrConflict

def GetMd5ConfAbs(md5abPath):
    ret = {}
    if not os.path.exists(md5abPath):
        return ret
    md5ab_file = open(md5abPath, 'r')
    for eachLine in md5ab_file:
        if eachLine.find('Luas/') > -1 or eachLine.find('ToLuaSrc/') > -1 or eachLine.find('=') < 0:
            # print "eachLine:" + eachLine
            continue
        abName = eachLine.split('=')[0]
        ret[abName] = True
    md5ab_file.close()
    return ret

def AddSVNByPath(path):
    if os.path.isfile(path) or os.path.isdir(path):
        ret, output = call('svn stat %s' % path)
        if output.find('?') == 0:
            addCmd = 'svn add %s %s' % (path, tmpUserPassword)
            print "addCmd: " + addCmd
            ret, output = call(addCmd)
            print output

def realRemove(path):
    if os.path.isfile(path):
        try:
            os.chmod(path, stat.S_IWRITE)
            os.remove(path)
        except Exception:
            print traceback.print_exc()
            print "os.remove failed " + path
    elif os.path.isdir(path):
        for root,dirs,files in os.walk(path):
            for file in files:
                fileName = os.path.join(root,file)
                if os.path.isfile(fileName):
                    try:
                        os.chmod(fileName, stat.S_IWRITE)
                        os.remove(fileName)
                    except Exception:
                        print traceback.print_exc()
                        print "os.remove failed " + fileName
    
        if os.path.isdir(path):
            try:
                shutil.rmtree(path)
            except Exception:
                print traceback.print_exc()
                print "shutil.rmtree failed " + path

def isPlatform32Bit():
    platform = plat.architecture()
    if platform[0] == "32bit" :
        return True
    
    return False

def GetSVNDirList(svnPath):
    cmdPrefix = ""    
    # cmdPrefix = "env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"
    SvnLog = '{} svn ls {} {}' 
    str_out = SvnLog.format(cmdPrefix, svnPath,tmpUserPassword)
    print("cmd: {0}".format(str_out))
    ret, output = call(str_out)
    import re
    pattern = "\d+\.\d+\.\d+\.\d+.*\n"
    tempDirList = re.findall(pattern, output)
    versionDirList = []
    for oneVersionDirName in tempDirList:
        pattern1 = "[\/\r\n]*"
        formatVersionDirName = re.sub(pattern1,'',oneVersionDirName)
        versionDirList.append(formatVersionDirName)
    return versionDirList
    
#将数组转换为字典
def ListToDic(templist):
    dic = {}
    for v in templist:
        dic[v] = v
    return dic

#获取两个svn版本之间的差异Excel表文件名
#revision1 svn版本号
#revision2 svn版本号
#path 指定路径
#pattern 筛选日志的匹配
def GetDiffFileNamesByRevision(revision1,revision2,path,pattern):
    lines = []
    fileNames = ""
    if len(revision1) == 0 or len(revision2) == 0:
        print("revision is not correct !!")
        return fileNames
    print("revision1: {0} revision2: {1}".format(revision1,revision2)) 
    print("path: {0} pattern: {1}".format(path,pattern))
    if plat.system() == 'Windows':
        cmdPrefix = ''   
    elif plat.system() == 'Darwin':
        cmdPrefix = "env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"
    if len(pattern) > 0:
        SvnLog = '{} svn log -r {}:{} {} {} --verbose --search {}' 
        str_out = SvnLog.format(cmdPrefix,revision1, revision2, path,tmpUserPassword,pattern)
    else:
        print("No Filter Log")
        SvnLog = '{} svn log -r {}:{} {} {} --verbose' 
        str_out = SvnLog.format(cmdPrefix,revision1, revision2, path,tmpUserPassword)
    
    print("diffCmd: {}".format(str_out))
    ret, output = call(str_out)
    if ret != 0:
        print("diffCmd failed !!!")
        traceback.print_exc()
        return fileNames
    import re
    print("diffLogMessage: {}".format(output))
    pattern = "\w*\.xlsx*"
    lines = re.findall(pattern, output)
    if len(lines) > 0:
        print("ChangeExcleList:\n{}".format("\n".join(lines)))
        fileDic = {}
        for v in lines:
            #去重
            fileDic[v] = v
        newLines = fileDic.values()
        fileNames = ",".join(newLines)
        fileNames = re.sub("\.xlsx","",fileNames)
        print("fileNames:{} ".format(fileNames))
        return fileNames
    else:
        print("NONE")
        return fileNames

#将提交人信息解析出RTX能识别的
def ParseAuthorUrlToAuthor(authorUrl):
    if authorUrl == None:
        return None
    pattern = '^([a-zA-Z]+)(@.*)'
    msgMatch = re.search(pattern, authorUrl)
    if msgMatch:
        return msgMatch.group(1)
    else:
        print("author is None authorUrl: {}".format(authorUrl))
        return None

#patch平台文件夹
def GetPatchPlatformFolderName(platform):
    platform = platform.lower()
    folderName = platform
    if platform == "pc":
		if isPlatform32Bit():
			folderName = "windows32"
		else:
			folderName = "windows64"
    return folderName

#版控平台文件夹
def GetVerConfPlatformFolderName(platform):
    platform = platform.lower()
    folderName = platform
    if platform == "pc":
		if isPlatform32Bit():
			folderName = "windows32"
		else:
			folderName = "windows64"
    return folderName

#Artifact平台文件夹
def GetArtifactPlatformFolderName(platform):
    platform = platform.lower()
    folderName = platform
    if platform == "pc":
		if isPlatform32Bit():
			folderName = "Windows32"
		else:
			folderName = "Windows64"
    elif platform == "android":
        folderName = "Android"
    elif platform == "ios":
        folderName = "IOS"
    elif platform == 'openharmony':
        folderName = "OpenHarmony"
    return folderName

#平台文件夹
def GetPlatformFolderName(platform):
    platform = platform.lower()
    folderName = platform
    if platform == "pc":
		if isPlatform32Bit():
			folderName = "Windows32"
		else:
			folderName = "Windows64"
    elif platform == "android":
        folderName = "Android"
    elif platform == "ios":
        folderName = "IOS"
    elif platform == 'openharmony':
        folderName = "OpenHarmony"
    return folderName

#还原并更新文件夹
def SvnUpdateByPath(path):
    isLockOrConfict = PathIsLockOrConflict(path)   
    if isLockOrConfict == True:
        print("path: {0} \n please cleanup !!".format(path))
        return 1
    cmdPrefix = '' 
    if plat.system() == 'Windows':
        cmdPrefix = ''   
    elif plat.system() == 'Darwin':
        cmdPrefix = "env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"

    cmd = "{0} svn revert {1} -R {2}".format(cmdPrefix,path,tmpUserPassword)
    print(cmd)
    ret,output = call(cmd)
    if ret != 0:
        print(output)
        return 1
    
    cmd = "{0} svn up {1} --accept=theirs-full {2}".format(cmdPrefix,path,tmpUserPassword)
    print(cmd)
    ret,output = call(cmd)
    if ret != 0:
        print(output)
        return 1
    return ret

#更新文件夹
def SvnUpdateOnlyByPath(path):
    isLockOrConfict = PathIsLockOrConflict(path)   
    if isLockOrConfict == True:
        print("path: {0} \n please cleanup !!".format(path))
        return 1
    cmdPrefix = '' 
    if plat.system() == 'Windows':
        cmdPrefix = ''   
    elif plat.system() == 'Darwin':
        cmdPrefix = "env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8"
    cmdStr = "{0} svn up {1} --accept=theirs-full {2}".format(cmdPrefix,path,tmpUserPassword)
    print(cmdStr)
    ret,output = call(cmdStr)
    if ret != 0:
        print(output)
        return 1
    return ret

def GetLongPath(path):
    srcName = path.replace("/", "\\")
    srcName = '\\\\?\\%s' % (srcName)
    return srcName

